﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FileDuplicateRemover.Core;

namespace FileDuplicateRemover.Test
{
    public class Program
    {
        private static ConsoleColor OldForegroundColor { get; set; }
        private static ConsoleColor FileEntityColor { get; set; }
        private static ConsoleColor DirectoryEntityColor { get; set; }
        private static ConsoleColor MainFileEntityColor { get; set; }
        private static ConsoleColor MainDirectoryEntityColor { get; set; }

        private static int Level { get; set; }

        private static StreamWriter StreamWriter { get; set; }

        public static void Main(string[] args)
        {
            Init();

            StreamWriter = new StreamWriter("out.txt");

            DirectoryEntity de = null;
            using (EntityTreeBuilder eb = new EntityTreeBuilder("c:\\FDR_TEST"))
            {
                de = eb.Create();
            }

            Level = 0;
            //PrintDirectoryEntity(de);

            //Console.WriteLine("-------- Done Print -------------------------");
            //Console.ReadLine();

            DuplicateEntityDescriptionList duplicateEntityList = new DuplicateEntityDescriptionList();
            EntityTreeWalker ec = new EntityTreeWalker();

            ec.Walk(de, duplicateEntityList.Add);

            IEnumerable<DuplicateEntityDescription> sortedList = duplicateEntityList.OrderBy(i => i.SomeEntity.Length);

            PrintDuplicateEntities(sortedList);

            Console.WriteLine("-------- Done Compare -------------------------");
            Console.ReadLine();

            //List<BaseEntity> duplicateEntityLst = CreateDuplicateEntityList(de);
            //duplicateEntityLst.Sort((x, y) => {
            //    int res = x.Length.CompareTo(y.Length);

            //    if (res == 0)
            //        res = x.FulltName.CompareTo(y.FulltName);

            //    return res;
            //});

            //PrintDuplicateEntityLst(duplicateEntityLst);

            //Console.WriteLine("-------- Done Print Duplicate Entity List -------------------------");
            //Console.ReadLine();

            StreamWriter.Close();
        }

        private static void Init()
        {
            OldForegroundColor = Console.ForegroundColor;
            Console.WindowWidth = 150;
            Console.WindowHeight = 44;
            Console.BufferHeight = 3000;

            FileEntityColor = ConsoleColor.Gray;
            DirectoryEntityColor = ConsoleColor.DarkYellow;

            MainFileEntityColor = ConsoleColor.White;
            MainDirectoryEntityColor = ConsoleColor.Yellow;
        }

        private static void PrintDirectoryEntity(DirectoryEntity de)
        {
            foreach (BaseEntity e in de.EntityList)
            {
                if (e is FileEntity)
                {
                    PrintCoreFileEntity(e as FileEntity, FileEntityColor);
                }
                else
                {
                    PrintCoreDirectoryEntity(e as DirectoryEntity, DirectoryEntityColor);

                    Level++;
                    PrintDirectoryEntity(e as DirectoryEntity);
                    Level--;
                }
            }
        }

        private static void PrintCoreDirectoryEntity(DirectoryEntity de, ConsoleColor color)
        {
            String str = String.Empty.PadLeft(Level * 2, ' ');
            string outStr = String.Format("{0}DIR(Length = {1:N0}, TotalEntityCount = {2:N0}) : [{3}]", str, de.Length, de.TotalEntityCount, de.FulltName);

            Console.ForegroundColor = color;
            Console.WriteLine(outStr);

            StreamWriter.WriteLine(outStr);
        }

        private static void PrintCoreFileEntity(FileEntity fe, ConsoleColor color)
        {
            String str = String.Empty.PadLeft(Level * 2, ' ');
            string outStr = String.Format("{0}FILE({1:N0}): [{2}]", str, fe.Length, fe.FulltName);

            Console.ForegroundColor = color;
            Console.WriteLine(outStr);

            StreamWriter.WriteLine(outStr);
        }

        private static void PrintDuplicateEntities(IEnumerable<DuplicateEntityDescription> duplicateEntityList)
        {
            foreach (DuplicateEntityDescription ed in duplicateEntityList)
            {
                if (ed.HaveDuplicate)
                {
                    if (ed.SomeEntity is FileEntity)
                    {
                        PrintCoreFileEntity(ed.SomeEntity as FileEntity, MainFileEntityColor);
                        PrintDuplicateEntityList(ed);
                    }
                    else
                    {
                        PrintCoreDirectoryEntity(ed.SomeEntity as DirectoryEntity, MainDirectoryEntityColor);
                        PrintDuplicateEntityList(ed);
                    }
                }
            }
        }

        private static void PrintDuplicateEntityList(IEnumerable<BaseEntity> ed)
        {
            Level++;

            Console.WriteLine("====COPIES=========================");
            StreamWriter.WriteLine("====COPIES=========================");

            foreach (BaseEntity e in ed)
            {
                if (e is FileEntity)
                {
                    PrintCoreFileEntity(e as FileEntity, FileEntityColor);
                }
                else
                {
                    PrintCoreDirectoryEntity(e as DirectoryEntity, DirectoryEntityColor);
                }
            }
            Console.WriteLine();
            StreamWriter.WriteLine();

            //Console.WriteLine("=====Press Enter========================");
            //Console.ReadLine();

            Level--;
        }
    }
}
